package com.mali.permission.service.impl;

import cn.hutool.http.HttpStatus;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.mali.common.db.enums.RoleEnum;
import com.mali.common.dto.Result;
import com.mali.common.exception.BizException;
import com.mali.common.web.domain.dto.PageRequestDTO;
import com.mali.mq.template.LogTemplate;
import com.mali.permission.domain.po.Permission;
import com.mali.permission.mapper.PermissionMapper;
import com.mali.permission.service.PermissionService;
import io.seata.spring.annotation.GlobalTransactional;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Collection;
import java.util.List;
import java.util.stream.Collectors;

import static com.mali.common.util.RoleConstant.*;

@Slf4j
@Service
@Transactional(rollbackFor = Exception.class)
@RequiredArgsConstructor
public class PermissionServiceImpl extends ServiceImpl<PermissionMapper, Permission> implements PermissionService {
    private final LogTemplate logTemplate;
    @Value("${spring.application.name}")
    private String serviceName;

    @Override
    @GlobalTransactional(rollbackFor = Exception.class, name = "permission-service-global-tx")
    public Result<String> bindDefaultRole(Long userId) {
        logTemplate.sendSuccessLog(serviceName, "DEFAULT_ROLE_BIND", "START", userId, userId, "开始绑定用户默认角色");

        if (userId == null) {
            logTemplate.sendFailLog(serviceName, "DEFAULT_ROLE_BIND", "VALIDATE", null, userId, "用户ID为空");
            return Result.fail("用户ID不能为空");
        }

        // 检查是否已有绑定
        Permission existing = getById(userId);
        if (existing != null) {
            logTemplate.sendFailLog(serviceName, "DEFAULT_ROLE_BIND", "CHECK_EXIST", userId, userId, "用户已存在绑定记录");
            return Result.fail("用户权限已存在");
        }

        // 创建权限绑定
        Permission permission = new Permission();
        permission.setUserId(userId);
        permission.setRole(RoleEnum.USER);

        boolean saved = save(permission);
        if (!saved) {
            logTemplate.sendFailLog(serviceName, "DEFAULT_ROLE_BIND", "SAVE", userId, userId, "保存权限记录失败");
            throw new BizException("绑定默认角色失败");
        }

        logTemplate.sendSuccessLog(serviceName, "DEFAULT_ROLE_BIND", "SUCCESS", userId, userId, "默认角色绑定成功，角色=" + RoleEnum.USER.getRole());
        return Result.success(permission.getRole().getRole());
    }

    @Override
    @GlobalTransactional(rollbackFor = Exception.class, name = "permission-service-global-tx")
    public Result<Integer> getRoleCode(Long userId) {
        logTemplate.sendSuccessLog(serviceName, "GET_ROLE_CODE", "START", userId, userId, "开始获取角色码");

        if (userId == null) {
            logTemplate.sendFailLog(serviceName, "GET_ROLE_CODE", "VALIDATE", null, userId, "用户ID为空");
            return Result.fail("用户ID不能为空");
        }

        Permission permission = getById(userId);
        if (permission == null) {
            logTemplate.sendFailLog(serviceName, "GET_ROLE_CODE", "NOT_FOUND", null, userId, "不存在该用户");
            return Result.fail("用户不存在");
        }

        Integer roleCode = permission.getRole().getCode();
        logTemplate.sendSuccessLog(serviceName, "GET_ROLE_CODE", "SUCCESS", userId, userId, "获取角色码成功，角色码=" + roleCode);

        return Result.success(roleCode);
    }


    @Override
    @GlobalTransactional(rollbackFor = Exception.class, name = "permission-service-global-tx")
    public Result<Boolean> updateToAdmin(Long userId) {
        logTemplate.sendSuccessLog(serviceName, "UPDATE_ROLE", "START", userId, userId, "开始更新用户角色为管理员");

        if (userId == null) {
            logTemplate.sendFailLog(serviceName, "UPDATE_ROLE", "VALIDATE", null, userId, "用户ID为空");
            return Result.fail("用户ID不能为空");
        }

        Result<Integer> roleCodeResult = getRoleCode(userId);
        Integer roleCode = roleCodeResult.getData();
        if (roleCode != null && roleCode.equals(ROLE_ADMIN_CODE)) {
            logTemplate.sendFailLog(serviceName, "UPDATE_ROLE", "ALREADY_ADMIN", userId, userId, "用户已是管理员");
            return Result.fail("用户已是管理员");
        }

        Permission permission = new Permission();
        permission.setUserId(userId);
        permission.setRole(RoleEnum.ADMIN);

        boolean updated = updateById(permission);
        if (!updated) {
            logTemplate.sendFailLog(serviceName, "UPDATE_ROLE", "UPDATE_FAIL", userId, userId, "更新权限记录失败");
            throw new BizException("更新权限失败");
        }

        logTemplate.sendSuccessLog(serviceName, "UPDATE_ROLE", "SUCCESS", userId, userId, "更新权限成功，权限=" + RoleEnum.ADMIN);
        return Result.success(true);
    }

    @Override
    @GlobalTransactional(rollbackFor = Exception.class, name = "permission-service-global-tx")
    public Result<Boolean> updateToUser(Long userId) {
        logTemplate.sendSuccessLog(serviceName, "UPDATE_ROLE", "START", userId, userId, "开始更新用户角色为普通用户");

        if (userId == null) {
            logTemplate.sendFailLog(serviceName, "UPDATE_ROLE", "VALIDATE", null, userId, "用户ID为空");
            return Result.fail("用户ID不能为空");
        }

        Result<Integer> roleCodeResult = getRoleCode(userId);
        Integer roleCode = roleCodeResult.getData();
        if (roleCode != null && roleCode.equals(ROLE_USER_CODE)) {
            logTemplate.sendFailLog(serviceName, "UPDATE_ROLE", "ALREADY_USER", userId, userId, "用户已是普通用户");
            return Result.fail("用户已是普通用户");
        }

        Permission permission = new Permission();
        permission.setUserId(userId);
        permission.setRole(RoleEnum.USER);

        boolean updated = updateById(permission);
        if (!updated) {
            logTemplate.sendFailLog(serviceName, "UPDATE_ROLE", "UPDATE_FAIL", userId, userId, "更新权限记录失败");
            throw new BizException("更新权限失败");
        }

        logTemplate.sendSuccessLog(serviceName, "UPDATE_ROLE", "SUCCESS", userId, userId, "更新权限成功，权限=" + RoleEnum.USER);
        return Result.success(true);
    }

    @Override
    public Result<Collection<Long>> getCommonUserList(PageRequestDTO pageRequestDTO) {
        logTemplate.sendSuccessLog(serviceName, "GET_USER_LIST", "START", null, null, "开始获取普通用户列表");
        Result<Collection<Long>> result = getCollectionResult(pageRequestDTO, ROLE_USER_CODE);
        if (result.getCode().equals(HttpStatus.HTTP_OK)) {
            logTemplate.sendSuccessLog(serviceName, "GET_USER_LIST", "SUCCESS", null, null, "获取普通用户列表成功，数量：" + (result.getData() != null ? result.getData().size() : 0));
        } else {
            logTemplate.sendFailLog(serviceName, "GET_USER_LIST", "FAIL", null, null, "获取普通用户列表失败：" + result.getMessage());
        }
        return result;
    }

    @Override
    public Result<Collection<Long>> getAdminUserList(PageRequestDTO pageRequestDTO) {
        logTemplate.sendSuccessLog(serviceName, "GET_ADMIN_LIST", "START", null, null, "开始获取管理员列表");
        Result<Collection<Long>> result = getCollectionResult(pageRequestDTO, ROLE_ADMIN_CODE);
        if (result.getCode().equals(HttpStatus.HTTP_OK)) {
            logTemplate.sendSuccessLog(serviceName, "GET_ADMIN_LIST", "SUCCESS", null, null, "获取管理员列表成功，数量：" + (result.getData() != null ? result.getData().size() : 0));
        } else {
            logTemplate.sendFailLog(serviceName, "GET_ADMIN_LIST", "FAIL", null, null, "获取管理员列表失败：" + result.getMessage());
        }
        return result;
    }

    @NotNull
    private Result<Collection<Long>> getCollectionResult(PageRequestDTO pageRequestDTO, Integer roleCode) {
        int pageNum = pageRequestDTO.getNum();
        int pageSize = pageRequestDTO.getSize();
        int offset = (pageNum - 1) * pageSize;

        LambdaQueryWrapper<Permission> wrapper = new QueryWrapper<Permission>()
                .lambda()
                .eq(Permission::getRole, roleCode)
                .last("LIMIT " + offset + ", " + pageSize);

        List<Permission> records = this.list(wrapper);

        if (records.isEmpty()) {
            logTemplate.sendFailLog(serviceName, "GET_USER_LIST", "EMPTY", null, null, "无目标用户，roleCode=" + roleCode);
            return Result.fail("没有目标用户");
        }

        logTemplate.sendSuccessLog(serviceName, "GET_USER_LIST", "SUCCESS", null, null, "获取目标用户列表成功，roleCode=" + roleCode + "，数量：" + records.size());
        return Result.success(records.stream().map(Permission::getUserId).collect(Collectors.toList()));
    }

}
